package com.lizardmind.haofudoctor.other

import android.content.Context
import android.content.Intent
import android.databinding.ViewDataBinding
import android.support.annotation.LayoutRes
import android.support.v7.widget.RecyclerView
import android.view.ViewManager
import android.widget.Toast
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.CleanUtils
import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.RegexUtils
import com.google.gson.Gson
import com.linxiao.framework.BaseApplication
import com.linxiao.framework.glide.GlideModuleConfig
import com.linxiao.framework.net.BaseAPI
import com.linxiao.framework.net.RetrofitManager
import com.linxiao.framework.net.interceptor.CacheInterceptor
import com.linxiao.framework.util.DelegatesExt
import com.linxiao.framework.util.RSAUtils
import com.linxiao.framework.util.fromJson
import com.linxiao.framework.util.ke
import com.lizardmind.haofudoctor.manager.NetManager
import com.lizardmind.haofudoctor.test.BaseBinder
import com.lizardmind.haofudoctor.ui.main.LoginActivity
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import me.drakeet.multitype.MultiTypeAdapter
import org.greenrobot.eventbus.EventBus
import org.jetbrains.anko.AnkoException
import org.jetbrains.anko.AnkoViewDslMarker
import org.jetbrains.anko.custom.ankoView
import org.jetbrains.anko.intentFor
import org.json.JSONObject
import retrofit2.HttpException
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.scalars.ScalarsConverterFactory
import java.io.IOException

/**
 *
 * Created by Extends on 2017/10/20 17:54
 */

object DoctorInfo{
    var id:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserId","")//用户Id
    var name:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserName","")//名称
    var phone:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserPhone","")//手机号
    var head_img:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserHeadImg","")//头像
    var sex:Int by DelegatesExt.preference(BaseApplication.getAppContext(),"UserSex",1)//性别 1男2女
    var cause:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserCause","")//从事
    var age:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserAge","")//年龄
    var type:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserType","")//医生类别
    var aera:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserAera","")//地址
    var hospital_name:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserHospitalName","")//医院名称
    var token:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserToken","")//token令牌
    var rToken:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserRongYunToken","")//rToken令牌

    //----------
    var introduce:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserIntroduce","")//介绍
    var gonggao:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserGongGao","")//公告
    var good_at:String by DelegatesExt.preference(BaseApplication.getAppContext(),"UserGoodAt","")//擅长

    /**
     * 将数据初始化
     * 因为doctorBean的来源是服务器返回的用户数据，可能某些数据
     * 是null的，但是定义时是不允许为null，所以IDE提示不用理
     */
    fun updataDoctor(doctorBean: DoctorBean){
        id = doctorBean.did?: id
        name = doctorBean.name?: name
        phone = doctorBean.phone?: phone
        head_img = doctorBean.head_img?: head_img
        sex = doctorBean.sex?:sex
        cause = doctorBean.cause?: cause
        age = doctorBean.age?: age
        type = doctorBean.type?: type
        aera = doctorBean.aera?: aera
        hospital_name = doctorBean.hospital_name?: hospital_name
        token = doctorBean.token?: token
        rToken = doctorBean.rToken?:rToken
    }

    fun clear(){
        id = ""
        name = ""
        phone = ""
        head_img = ""
        sex = 1
        cause = ""
        age = ""
        type = ""
        aera = ""
        hospital_name = ""
        token = ""
    }
}

inline fun ViewManager.recyclerView(init: (@AnkoViewDslMarker RecyclerView).() -> Unit): RecyclerView {
    return ankoView({ctx: Context -> RecyclerView(ctx) }, theme = 0) { init() }
}



object Config{
    var pk:String by DelegatesExt.preference(BaseApplication.getAppContext(),"pk","")
    /**
     * 获取公钥
     */
    fun getPK(){
       RetrofitManager.createRetrofitBuilder(NetManager.baseUrl)
                .addConvertFactory(ScalarsConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addCustomInterceptor(CacheInterceptor())
                .build(BaseAPI::class.java)
                .postApi(hashMapOf("action" to "key_encrypted"),0)
                .subscribeOn(Schedulers.io())
                .retry(3)
                .doOnNext { ke(it) }
                .map { Gson().fromJson<Request<String>>(it) }
                .observeOn(AndroidSchedulers.mainThread())
                .unsubscribeOn(Schedulers.io())
                .subscribe({
                    it.dispose {
                        pk = it
                        RSAUtils.loadPublicKey(it)
                    }
                }, {
                    Toast.makeText(BaseApplication.getAppContext(),
                            when(it){
                                is HttpException ->"服务暂不可用"
                                is IOException ->"连接服务器失败"
                                else->it.message
                            }, Toast.LENGTH_SHORT).show()
                }, {
                    EventBus.getDefault().post(PKEvent(pk.isNotEmpty()))
                })
    }

    val sizeUnit= arrayOf("B","KB","MB","GB","TB","PB","EB")
    fun unitConversion(l:Long,unit:Int=0):String{
        if(l<1024 || unit== sizeUnit.count()-1)return l.toString()+ sizeUnit[unit]
        return unitConversion(l/1024,unit+1)
    }
}

/**
 * 获取缓存文件大小
 */
fun getCacheFileSize():String{
    val l = FileUtils.getDirLength(GlideModuleConfig.path)
    val ps2 = FileUtils.getDirLength(BaseApplication.getAppContext().cacheDir.path)
    return Config.unitConversion(l+ps2)
}

/**
 * 清空缓存文件
 */
fun clearCacheFile():Boolean{
    val c1 = CleanUtils.cleanCustomCache(GlideModuleConfig.path)
    val c2 = CleanUtils.cleanCustomCache(BaseApplication.getAppContext().cacheDir.path)
    return c1&&c2
}

/**
 * 退出登陆
 */
fun logOut(){
    //清除个人数据
    DoctorInfo.clear()
    //关闭所有界面，打开登陆界面
    ActivityUtils.finishAllActivities()
    BaseApplication.getAppContext().apply {
        startActivity(intentFor<LoginActivity>().apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) })
    }
}

/**
 * 验证密码是否符合格式
 * 正则表达式校验密码
 * 1、密码必须由数字、字符、特殊字符三种中的两种组成；
 * 2、密码长度不能少于8个字符；
 */
fun checkPassWord(str:String):Boolean = RegexUtils.isMatch("""(?!^[0-9]+$)(?!^[a-zA-Z]+$)(?!^[_#@]+$).{8,}""",str)

inline fun <reified T,V: ViewDataBinding> MultiTypeAdapter.register(@LayoutRes layoutId:Int):BaseBinder<T,V>{
    val binder = BaseBinder<T,V>(layoutId)
    register(T::class.java, binder)
    return binder
}


/**
 * ----------------------------------------JSON--------------------------------------------------------------------------------
 */
fun <V> jsonOf(vararg pairs: Pair<String, V>):JSONObject{
    val json = JSONObject()

    pairs.forEach {
        val value = it.second
        when(value){
            null ->{}
            is Int -> json.put(it.first,value)
            is Long -> json.put(it.first,value)
            is Double -> json.put(it.first,value)
            is Boolean -> json.put(it.first,value)
            is Any -> json.put(it.first,value)
        }
    }
    return json
}

/**
 * 格式化给曾焱
 */
inline fun JSONObject.formatToZY() = toString().replace("\"","\\\"")